﻿using System;
using System.Collections.Generic;
using System.Linq;
using DataStore.Domain;
using NHibernate;
using NHibernate.Linq;

namespace DataStore.Repositories
{
    /// <summary>
    /// Autor repository
    /// </summary>
    public class AuthorRepository : IRepository<Author>
    {
        readonly UnitOfWork _unitOfWork;

        /// <summary>
        /// Initializes a new instance of the <see cref="AuthorRepository"/> class.
        /// </summary>
        public AuthorRepository()
        {
            
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="AuthorRepository"/> class.
        /// </summary>
        /// <param name="unitOfWork">The unit of work.</param>
        public AuthorRepository(UnitOfWork unitOfWork) : this()
        {
            _unitOfWork = unitOfWork;
        }

        #region IAuthorRepository Members


        public Author Get(object id)
        {
            ISession session = _unitOfWork.Session;
            return session.Get<Author>(id);
        }

        public void Delete(Author entity)
        {
            ISession session = _unitOfWork.Session;
            session.Delete(entity);
        }

        public void DeleteAll()
        {
            throw new NotImplementedException();
        }

        public void Save(Author entity)
        {
            ISession session = _unitOfWork.Session;
            session.Save(entity);
        }

        public Author SaveOrUpdate(Author entity)
        {
            ISession session = _unitOfWork.Session;
            session.SaveOrUpdate(entity);
            return entity;
        }

        public void Update(Author entity)
        {
            ISession session = _unitOfWork.Session;
            session.Update(entity);
        }

        IEnumerable<Author> IRepository<Author>.All
        {
            get 
            {
                ISession session = _unitOfWork.Session;
                return session.Linq<Author>().ToList();
            }
        }

        /// <summary>
        /// Gets the authors with the same name.
        /// </summary>
        /// <param name="author">The author.</param>
        /// <returns>The authors in the database.</returns>
        public ICollection<Author> GetAuthors(Author author)
        {
            ISession session = _unitOfWork.Session;
            var authors = from a in session.Linq<Author>()
                          where a.FirstName == author.FirstName &&
                                a.MiddleName == author.MiddleName &&
                                a.LastName == author.LastName
                          select a;

            return authors.ToList();

        }

        /// <summary>
        /// Checks if the specified author exists.
        /// </summary>
        /// <param name="author">The author.</param>
        /// <returns>[true] if exists; otherwise [false]</returns>
        public bool Exists(Author author)
        {
            ISession session = _unitOfWork.Session;
            var authorCount = (from a in session.Linq<Author>()
                          where a.FirstName == author.FirstName &&
                                a.MiddleName == author.MiddleName &&
                                a.LastName == author.LastName
                          select  a).Count();

            return authorCount > 0;
        }

        public bool IsEmpty
        {
            get { throw new NotImplementedException(); }
        }

        public int Count(Author entity)
        {
            throw new NotImplementedException();
        }

        public int CountAll()
        {
            throw new NotImplementedException();
        }

        #endregion
    }
}
